import { Context } from "koa";
import path from "path";
import fs from 'fs';
import response from "../../utils/response";

class UploadController {
  /** get请求访问upload上传页面 */
  index(ctx: Context) {
    console.log('get请求上传页面');
    console.log(ctx.request.body);
    response.success(ctx, ['UploadController-get请求上传页面']);
  }

  /** post请求访问upload上传页面 */
  postIndex(ctx: Context){
    console.log('post请求上传页面');
    console.log(ctx.request.body);
    response.success(ctx, ['UploadController-Post请求上传页面']);
  }

  /** post请求访问上传单个文件页面 */
  postUploadFile = (ctx: Context) => {
    // 获取上传文件
    //koa-body v3和v4之前通过ctx.request.body捕获文件。而v3.v4终才是通过ctx.request.files.file进行获取
    const file:any = ctx.request.files?.file;

    if (file) {
      //数据验证
      const fileType = file.type;
      const typeSet = new Set(['image/jpeg', 'image/jpg', 'image/gif', 'image/png']);
      if (!typeSet.has(fileType)) {
        return response.error(ctx,'非法文件上传');
      }

      // 创建可读流
      const reader = fs.createReadStream(file.path);

      // 最终要保存到的文件夹目录
      const dirName = this.getUploadDirName(); //yyyy-mm-dd
      const dir = path.join(__dirname, '..', '..', `assets/upload-files/${dirName}`);

      // 检查文件夹是否存在如果不存在则新建文件夹
      this.checkDirExist(dir);
      
      // 文件名称去掉特殊字符但保留原始文件名称.replace(/\s*/, "_")
      const fileName = file.name.replace(/[`~!@#$%^&*()|\-=?;:'",<>\{\}\\\/]/gi, "_");
      file.name = fileName;

      // 覆盖文件存放的完整路径(保留原始名称)
      file.path = `${dir}/${fileName}`;

      // 创建可写流
      const upStream = fs.createWriteStream(file.path);

      // 可读流通过管道写入可写流
      reader.pipe(upStream);

      //返回数据
      // 提取出用 '/' 隔开的path的最后一部分
      const baseName = path.basename(file.path);
      let data = {
        "url": `${ctx.origin}/upload-files/${baseName}`,
        "path": file.path,
        "name": file.name,
        "type": file.type
      };
      console.log(file.path, file.name, file.type);
      response.success(ctx, data);
    } else {
      response.error(ctx, '文件不可以为空');
    }
  }

  /** post请求访问上传多个文件页面 */
  postUploadFiles(ctx: Context) {
    const files: any = ctx.request.files?.file; // 获取上传文件
    for (let file of files) {
      // 创建可读流
      const reader = fs.createReadStream(file.path);
      // 获取上传文件扩展名
      let filePath = path.join(__dirname, 'assets/upload-files/') + `/${file.name}`;
      // 创建可写流
      const upStream = fs.createWriteStream(filePath);
      // 可读流通过管道写入可写流
      reader.pipe(upStream);
    }
    return ctx.body = "上传成功！";
  }

  /** 生成随机字符串 */
  randomStr = (length: number): string => {
    const seeder = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';    /****默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/
    let randomStr = ''
    for (let i = 0; i < length; i++) {
      randomStr += seeder.charAt(Math.floor(Math.random() * seeder.length))
    }
    return randomStr
  }

  /** 生成文件夹名称 */
  getUploadDirName() {
    const date = new Date();
    let month: string | number = date.getMonth() + 1;
    month = month.toString().length > 1 ? month : `0${month}`;
    const dir = `${date.getFullYear()}-${month}-${date.getDate()}`;
    return dir;
  }

  /** 判断文件夹是否存在 如果不存在则创建文件夹 */
  checkDirExist(filename:any) {
    if (!fs.existsSync(filename)) {
      fs.mkdirSync(filename);
    }
  }
}

export default new UploadController